﻿using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using Microsoft.Win32;
using ModelCoding.Entity;
using ModelCoding.Helpers;
using ModelCoding.IServices;
using ModelCoding.Services;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;

namespace ModelCoding.ViewModel
{
    public class HomeViewModel : ViewModelBase
    {
        public HomeViewModel()
        {
            MenuList = new ObservableCollection<HomeMenu>{
                new HomeMenu{Icon="Gear",MenuName="配置服务器",IsChecked=true,
                    Command =new RelayCommand(() => SettingServerMethod()) },

                new HomeMenu{Icon="Database",MenuName="选择数据库",
                    Command =new RelayCommand(()=> 
                    {
                        SelectedIndex = 2;
                        Task.Run(async ()=> await SettingConnectionMethod());
                    })
                }
            };


            //选择数据库
            CheckedDataBaseCommand = new RelayCommand<string>(  Name => {
                SelectedIndex = 2;
                Task.Run(async()=> await OnGetTables(Name));
            });
            //选择表
            CheckedTableCommand = new RelayCommand<string>(Name =>
            {
                CheckCount = TableList.Count(x => x.IsChecked);
            });
            PreviewCommand = new RelayCommand<string>(TableName=>PreviewMethod(TableName));

            //生成
            ApplyCommand = new RelayCommand(ApplyMethod);

            //清空
            ClearCommand = new RelayCommand(() =>
            {
                var newList = TableList.Select(x =>
               {
                   x.IsChecked = false;
                   return x;
               });
                TableList = new ObservableCollection<TableModel>(newList);
                CheckCount = 0;

                //清空去除路径
                Paths = string.Empty;
                Cache.Paths = string.Empty;
            });


            Server = Cache.Server;
            UserName = Cache.UserName;
            PassWord = Cache.PassWord;
            Paths=Cache.Paths;
            NameSpaces=Cache.NameSpaces;
        }

        private void PreviewMethod(string tableName)
        {
            if (Validate(true) && !string.IsNullOrEmpty(tableName))
            {
                if (string.IsNullOrEmpty(NameSpaces))
                {
                    DialogHelper.ShowDialog("请输入命名空间后重试！");
                    return;
                }
                var bs = db.GetDataTable(Server, DataBaseName, UserName, PassWord, tableName);
                if (bs.Code == 200)
                {
                    DataTable dt = bs.Data as DataTable;
                    if (dt != null)
                    {
                        var code = CreateCode(dt);
                        DialogHelper.ShowPreview(code);
                    }
                }
                else
                {
                    DialogHelper.ShowDialog(bs.Message);
                }
            }
        }

        private void ApplyMethod()
        {
            if (Validate())
            {
                var TableCount = TableList.Count(x => x.IsChecked);
                if (string.IsNullOrEmpty(DataBaseName))
                {
                    DialogHelper.ShowDialog("请先选择数据库！");
                }
                else if (string.IsNullOrEmpty(NameSpaces))
                {
                    DialogHelper.ShowDialog("请输入命名空间后重试！");
                }
                else if (TableCount == 0)
                {
                    DialogHelper.ShowDialog("您还没有选择数据表，请检查后重试！");
                }
                else
                {
                    Cache.NameSpaces = NameSpaces;
                    var IsCheckedPath = false;
                    //开始生成
                    //选择一个地址
                    if (string.IsNullOrEmpty(Paths))
                    {
                        WPFFolderBrowser.WPFFolderBrowserDialog dialog = new WPFFolderBrowser.WPFFolderBrowserDialog();
                        if (dialog.ShowDialog().Value)
                        {
                            Paths = dialog.FileName;
                            Cache.Paths = Paths;
                            IsCheckedPath = true;
                        }
                    }
                    if (!IsCheckedPath)
                    {
                        DialogHelper.ShowDialog("请选择导出地址后重试。");
                        return;
                    }

                    //已选择文件夹 
                    if (DialogHelper.ShowDialog("是否开始生成模型？导出至：" + Paths))
                    {
                        SelectedIndex = 2;
                        Task.Run(() =>
                        {
                            var CheckedTableList = TableList.Where(x => x.IsChecked).Select(x => x.TableName).ToList();
                            var result = db.GetDataSet(Server, DataBaseName, UserName, PassWord, CheckedTableList);
                            if (result.Code == 200)
                            {
                                DataSet ds = result.Data as DataSet;
                                if (ds.Tables.Count > 0)
                                {
                                    var IsSuccess = CreateModel(ds);
                                    if (IsSuccess)
                                    {
                                        SelectedIndex = 1;
                                        DialogHelper.ShowDialog("生成成功！");
                                    }
                                    else
                                    {
                                        SelectedIndex = 1;
                                        DialogHelper.ShowDialog("生成失败,请稍后重试！");
                                    }
                                }
                            }
                            else
                            {
                                DialogHelper.ShowDialog(result.Message);
                            }
                        });

                    }


                }
            }
        }


        /// <summary>
        /// 生成模型代码
        /// </summary>
        /// <param name="tab"></param>
        /// <returns></returns>
        public string CreateCode(DataTable tab)
        {
            try
            {
                //生成代码
                StringBuilder sd = new StringBuilder();
                sd.AppendLine("using System;");
                sd.AppendLine("namespace " + NameSpaces);
                sd.AppendLine("{");
                //----类
                sd.AppendLine($"    public class {tab.TableName}");
                sd.AppendLine("     {");
                //获取当前数据表的所有列
                foreach (DataColumn col in tab.Columns)
                {
                    //---字段
                    sd.Append($"        public {GetColType(col)} {col.ColumnName} ").AppendLine("{ get; set; }");
                    //---字段
                }
                sd.AppendLine("     }");
                //----类
                sd.AppendLine("}");

                var str = sd.ToString();

                return str;
            }
            catch (Exception ex)
            {
                return null;
            }
        }

        /// <summary>
        /// 导出模型
        /// </summary>
        /// <param name="ds"></param>
        /// <returns></returns>
        private bool CreateModel(DataSet ds)
        {
            try
            {
                //遍历每一张表
                foreach (DataTable tab in ds.Tables)
                {
                    var str = CreateCode(tab);

                    //生成文件  导入到指定位置
                    string fileName = Path.Combine(Paths, tab.TableName + ".cs");
                    using (FileStream fs = new FileStream(fileName, FileMode.OpenOrCreate))
                    {
                        byte[] array = Encoding.Default.GetBytes(str);
                        fs.Write(array, 0, array.Length);
                    }
                }

                return true;
            }
            catch (Exception ex)
            {
                return false;
            }
        }

        /// <summary>
        /// 获取类型
        /// </summary>
        /// <param name="dc"></param>
        /// <returns></returns>
        public string GetColType(DataColumn dc)
        {
            //是否是可空  并且是一个值类型
            if (dc.AllowDBNull && dc.DataType.IsValueType)
            {
                return dc.DataType.Name + "?";
            }
            else
            {
                return dc.DataType.Name.ToString();
            }
        }



        private async Task OnGetTables(string Name)
        {
            try
            {
                DataBaseName = Name;
                //获取表
                if (Validate(true))
                {


                    var bs = await db.GetTable(Server, DataBaseName, UserName, PassWord);
                    if (bs.Code == 200)
                    {
                        var list = bs.Data as List<TableModel>;

                        TableList = new ObservableCollection<TableModel>(list);
                        CheckCount = list.Count;
                    }
                    else
                    {
                        DialogHelper.ShowDialog(bs.Message);
                    }

                }
            }
            catch (Exception ex)
            {
                DialogHelper.ShowDialog(ex.Message);
            }
            finally
            {
                SelectedIndex = 1;
            }
        }

        private async Task SettingConnectionMethod()
        {
            var succ = await OnConnectionMethod();
            if (succ)
            {
                SelectedIndex = 1;
                Cache.Server = Server;
                Cache.UserName = UserName;
                Cache.PassWord = PassWord;

                DataBaseName = string.Empty;
                TableList = new ObservableCollection<TableModel>();
                CheckCount = 0;
            }
            else
            {
                SelectedIndex = 0;
                CheckMenu(0);
            }

        }

        
        private void CheckMenu(int index)
        {
            if (index <= MenuList.Count - 1)
            {
                var list = MenuList.Select(x => { x.IsChecked = false; return x; }).ToList();
                list[index].IsChecked = true;
                MenuList = new ObservableCollection<HomeMenu>(list);
            }
        }

        private void SettingServerMethod()
        {
            SelectedIndex = 0;
        }

        IDbServices db = new DbServices();

        //打开连接
        private async Task<bool> OnConnectionMethod()
        {
            try
            {
                if (Validate())
                {
                    var bs = await db.GetDataBase(Server, UserName, PassWord);
                    if (bs.Code == 200)
                    {
                        DataBaseList = new ObservableCollection<DataBaseModel>(bs.Data as List<DataBaseModel>);
                        return true;
                    }
                    else
                    {
                        DialogHelper.ShowDialog(bs.Message);
                    }
                }

            }
            catch (Exception ex)
            {
                DialogHelper.ShowDialog(ex.Message);
            }
            return false;
        }

        bool Validate(bool IsValiDataBaseName = false)
        {
            if (string.IsNullOrEmpty(Server))
            {
                DialogHelper.ShowDialog("请填写服务器地址后重试！");
                return false;
            }
            else if (string.IsNullOrEmpty(UserName))
            {
                DialogHelper.ShowDialog("请输入您的服务器用户名！");
                return false;
            }
            else if (string.IsNullOrEmpty(PassWord))
            {
                DialogHelper.ShowDialog("请输入您的服务器登录密码！");
                return false;
            }

            if (IsValiDataBaseName)
            {
                if (string.IsNullOrEmpty(DataBaseName))
                {
                    DialogHelper.ShowDialog("请选择数据库后重试！");
                    return false;
                }
            }
            return true;
        }

        #region 属性


        private string _Server;
        public string Server
        {
            get { return _Server; }
            set { _Server = value; RaisePropertyChanged(); }
        }


        private string _UserName;
        public string UserName
        {
            get { return _UserName; }
            set { _UserName = value; RaisePropertyChanged(); }
        }

        private string _DataBaseName;
        public string DataBaseName
        {
            get { return _DataBaseName; }
            set { _DataBaseName = value; RaisePropertyChanged(); }
        }

        private string _PassWord;
        public string PassWord
        {
            get { return _PassWord; }
            set { _PassWord = value; RaisePropertyChanged(); }
        }

        private int _CheckCount;
        public int CheckCount
        {
            get { return _CheckCount; }
            set { _CheckCount = value; RaisePropertyChanged(); }
        }


        private string _NameSpaces;
        public string NameSpaces
        {
            get { return _NameSpaces; }
            set { _NameSpaces = value; RaisePropertyChanged(); }
        }


        private string _Paths;
        public string Paths
        {
            get { return _Paths; }
            set { _Paths = value; RaisePropertyChanged(); }
        }


        private int _SelectedIndex;
        public int SelectedIndex
        {
            get { return _SelectedIndex; }
            set { _SelectedIndex = value; RaisePropertyChanged(); }
        }


        private ObservableCollection<TableModel> _TableList;
        public ObservableCollection<TableModel> TableList
        {
            get { return _TableList; }
            set { _TableList = value; RaisePropertyChanged(); }
        }


        private ObservableCollection<DataBaseModel> _DataBaseList;
        public ObservableCollection<DataBaseModel> DataBaseList
        {
            get { return _DataBaseList; }
            set { _DataBaseList = value; RaisePropertyChanged(); }
        }


        private ObservableCollection<HomeMenu> _MenuList;
        public ObservableCollection<HomeMenu> MenuList
        {
            get { return _MenuList; }
            set { _MenuList = value; RaisePropertyChanged(); }
        }

        #endregion

        #region 命令

        public RelayCommand ApplyCommand { get; set; }
        public RelayCommand ClearCommand { get; set; }


        public RelayCommand<string> CheckedDataBaseCommand { get; set; }
        public RelayCommand<string> CheckedTableCommand { get; set; }
        public RelayCommand<string> PreviewCommand { get; set; }

        #endregion


        /// <summary>
        /// 菜单配置类
        /// </summary>
        public class HomeMenu
        {
            public string Icon { get; set; }
            public string MenuName { get; set; }

            public bool IsChecked { get; set; }
            public RelayCommand Command { get; set; }
        }
    }
}
